from torch.nn import CrossEntropyLoss
import math
def loss_fuc(output, target, pad_id=1):
    not_ignore = target.ne(pad_id)  # 进行非运算，返回一个tensor，若targets_view的第i个位置为pad_id，则置为0，否则为1
    num_targets = not_ignore.long().sum().item()  # 计算target中的非pad_id的数量

    loss_fct = CrossEntropyLoss(ignore_index=pad_id, reduction='sum')
    output = output.contiguous().view(-1, output.size(-1))
    target = target.contiguous().view(-1)
    loss = loss_fct(output, target)
    log_ppl = (1 / num_targets) * loss.item()
    ppl = math.exp(log_ppl)
    return loss, ppl